Week 3 of 16

Prompt Manager Complete + Week 3 Review

Finish the tool. Lock in the week. Three functions to go.

Day 15 60 minutes Build

Day 15 of 80

Today's Goals

Yesterday you built the menu loop and four foundational functions. Options 3, 4, and 5 were stubbed out. Today you replace those stubs with real code:

Menu Option Function What It Does
3 — Search search_prompts() Filter by keyword across all three fields
4 — Delete delete_prompt() Show list, ask for number, remove it, save
5 — Export export_by_platform() Group prompts by platform, write one file per platform

After writing the three functions, you'll swap out the placeholder print() lines in the menu loop and run a full test of all six options.

The Search Function

Search works by checking if the user's keyword appears in any of the three text fields of each prompt. The key tool here is a list comprehension — a concise way to filter a list.

prompt_manager_v2.py Python
def search_prompts(prompts):
    """Filter the library by a keyword and display matching prompts."""
    query = input("\nSearch (keyword or platform name): ").lower()
    # .lower() means searching "kling" and "Kling" both match

    # List comprehension — reads as:
    # "Give me each p from prompts WHERE the query appears in any field"
    # This replaces a for loop + if + append pattern in one readable line
    results = [
        p for p in prompts
        if query in p["platform"].lower()
        or query in p["shot"].lower()
        or query in p["prompt"].lower()
    ]

    if not results:
        print(f"\n  No prompts matching '{query}'.\n")
        return

    print(f"\n--- Found {len(results)} match(es) ---\n")
    # Display results the same way show_all() does
    for i, p in enumerate(results):
        print(f"  {i + 1}. [{p['platform']}] {p['shot']}")
        print(f"     {p['prompt'][:60]}...\n")
List Comprehensions — The One-Line Filter

The long way to search would be:

results = []
for p in prompts:
    if query in p["platform"].lower():
        results.append(p)

The list comprehension does the same thing in one line: [p for p in prompts if query in p["platform"].lower()]. It's not shorter just for style — it's a standard Python pattern that every programmer will recognize immediately.

The Delete Function

Delete shows the list, asks for a number, converts the input string to an integer, validates it, then uses .pop() to remove that item from the list.

prompt_manager_v2.py Python
def delete_prompt(prompts):
    """Show the full list, ask which number to delete, remove it."""
    if not prompts:
        print("\n  Nothing to delete.\n")
        return

    # Show the numbered list so the user knows what to type
    show_all(prompts)
    choice = input("Delete which number? (or 'cancel'): ")

    if choice.lower() == "cancel":
        return

    # try/except here because int("abc") raises ValueError
    # We never trust raw user input when we need a number
    try:
        # Subtract 1 because the menu shows 1-based numbers,
        # but Python lists are 0-based
        index = int(choice) - 1

        # Guard against negative numbers and numbers beyond list length
        if index < 0 or index >= len(prompts):
            print("  Invalid number.\n")
            return

        # .pop(index) removes the item at that position AND returns it
        # so we can tell the user what was deleted
        removed = prompts.pop(index)
        save_prompts(prompts)
        print(f"\n  Deleted: [{removed['platform']}] {removed['shot']}\n")

    except ValueError:
        # int("abc") → ValueError, caught here instead of crashing
        print("  Please enter a number.\n")
Why try/except ValueError?

If the user types "two" instead of "2", calling int("two") raises a ValueError and the script would crash without try/except. The except block catches that specific error and prints a friendly message. This pattern — validate numeric input with try/except ValueError — is one you'll use in almost every script that takes user input.

The Export Function

Export groups prompts by platform and writes a separate JSON file for each platform. The trick is building a dictionary of lists — one key per platform, each key holding a list of that platform's prompts.

prompt_manager_v2.py Python
def export_by_platform(prompts):
    """Group prompts by platform and write one JSON file per platform."""
    if not prompts:
        print("\n  Nothing to export.\n")
        return

    # Build a dict like: {"Kling": [...], "Runway": [...], "Veo": [...]}
    # We start with an empty dict and add keys as we encounter new platforms
    grouped = {}
    for p in prompts:
        platform = p["platform"]
        if platform not in grouped:
            # First time we see this platform — create an empty list for it
            grouped[platform] = []
        grouped[platform].append(p)

    # Now write one file per platform
    # .items() gives us (key, value) pairs from the dictionary
    for platform, platform_prompts in grouped.items():
        # Build a safe filename: "prompts_kling.json", "prompts_runway.json", etc.
        filename = f"prompts_{platform.lower()}.json"
        with open(filename, "w") as f:
            json.dump(platform_prompts, f, indent=2)
        print(f"  Exported {len(platform_prompts)} prompts to {filename}")

    print()

Putting It All Together

Update the menu loop at the bottom of prompt_manager_v2.py — replace the three placeholder print() lines with real function calls:

prompt_manager_v2.py — complete menu loop Python
prompts = load_prompts()

while True:
    print("\n========== Prompt Manager ==========")
    print("  1. View all prompts")
    print("  2. Add a prompt")
    print("  3. Search prompts")
    print("  4. Delete a prompt")
    print("  5. Export by platform")
    print("  6. Quit")
    print("===================================\n")

    choice = input("Choose (1-6): ").strip()

    if   choice == "1": show_all(prompts)
    elif choice == "2": add_prompt(prompts)
    elif choice == "3": search_prompts(prompts)   # was placeholder
    elif choice == "4": delete_prompt(prompts)    # was placeholder
    elif choice == "5": export_by_platform(prompts) # was placeholder
    elif choice == "6":
        print("\n  Bye!\n")
        break
    else:
        print("  Invalid choice. Enter 1-6.\n")

Run It and Test Everything

Terminal — full session
$ python prompt_manager_v2.py

========== Prompt Manager ==========
  1. View all prompts  ...
Choose (1-6): 3

Search (keyword or platform name): kling

--- Found 1 match(es) ---

  1. [Kling] Golf swing follow-through
     Slow-motion golf swing, camera tracks club head through i...

Choose (1-6): 4

--- All Prompts (3) ---
  1. [Kling] Golf swing follow-through ...
  2. [Runway] Ocean aerial ...
  3. [Veo] City timelapse at night ...

Delete which number? (or 'cancel'): 2

  Deleted: [Runway] Ocean aerial

Choose (1-6): 5

  Exported 1 prompts to prompts_kling.json
  Exported 1 prompts to prompts_veo.json

Choose (1-6): 6

  Bye!

Week 3 Milestone Check

What You Can Now Do

By the end of Week 3, you can:

That's a real, useful, production-relevant set of skills. You've built something you could actually hand to another person to use.

End of Day Checklist

Tomorrow

Week 4 starts Monday with APIs. You'll watch a short lesson on what an API actually is, then spend the rest of the week making real calls to the Claude API and building a tool that auto-generates video prompts for you.